package store.lunangangster.engine.impl.service;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import store.lunangangster.engine.ProcessEngineConfiguration;
import store.lunangangster.engine.impl.cmd.GetVariablesCmd;
import store.lunangangster.engine.impl.cmd.SetVariablesCmd;
import store.lunangangster.engine.impl.cmd.StartProcessCmd;
import store.lunangangster.engine.impl.runtime.ProcessInstance;
import store.lunangangster.engine.service.RuntimeService;

public class RuntimeServiceImpl extends ServiceImpl implements RuntimeService {

  public RuntimeServiceImpl(
      ProcessEngineConfiguration processEngineConfiguration) {
    super(processEngineConfiguration);
  }

  @Override
  public ProcessInstance startProcessInstanceByKey(String processDefinitionKey) {
    return executor.execute(new StartProcessCmd(null, processDefinitionKey));
  }

  @Override
  public ProcessInstance startProcessInstanceByKey(String processInstanceName,
      String processDefinitionKey) {
    return executor.execute(new StartProcessCmd(processInstanceName, null, processDefinitionKey, null));
  }

  @Override
  public ProcessInstance startProcessInstanceByKey(String processDefinitionKey,
      Map<String, Object> variables) {
    return executor.execute(new StartProcessCmd(null, null, processDefinitionKey, variables));
  }

  @Override
  public ProcessInstance startProcessInstanceByKey(String processInstanceName,
      String processDefinitionKey, Map<String, Object> variables) {
    return executor.execute(new StartProcessCmd(processInstanceName, null, processDefinitionKey, variables));
  }

  @Override
  public ProcessInstance startProcessInstanceById(String processDefinitionId) {
    return executor.execute(new StartProcessCmd(processDefinitionId, null));
  }

  @Override
  public ProcessInstance startProcessInstanceById(String processInstanceName,
      String processDefinitionId) {
    return executor.execute(new StartProcessCmd(processInstanceName, processDefinitionId, null, null));
  }

  @Override
  public ProcessInstance startProcessInstanceById(String processDefinitionId,
      Map<String, Object> variables) {
    return executor.execute(new StartProcessCmd(null, processDefinitionId, null, variables));
  }

  @Override
  public ProcessInstance startProcessInstanceById(String processInstanceName,
      String processDefinitionId, Map<String, Object> variables) {
    return executor.execute(new StartProcessCmd(processInstanceName, processDefinitionId, null, variables));
  }

  @Override
  public void setVariable(String variableName, Object value, String executionId) {
    Map<String, Object> map = new HashMap<>(1);
    map.put(variableName, value);
    executor.execute(new SetVariablesCmd(map, executionId, false));
  }

  @Override
  public void setVariables(Map<String, Object> variables, String executionId) {
    executor.execute(new SetVariablesCmd(variables, executionId, false));
  }

  @Override
  public void setLocalVariable(String variableName, Object value, String executionId) {
    Map<String, Object> map = new HashMap<>(1);
    map.put(variableName, value);
    executor.execute(new SetVariablesCmd(map, executionId, true));
  }

  @Override
  public void setLocalVariables(Map<String, Object> variables, String executionId) {
    executor.execute(new SetVariablesCmd(variables, executionId, true));
  }

  @Override
  public Object getVariable(String variableName, String executionId) {
    return executor.execute(new GetVariablesCmd(Collections.singleton(variableName), executionId)).get(variableName);
  }

  @Override
  public Map<String, Object> getVariables(Collection<String> variableNames, String executionId) {
    return executor.execute(new GetVariablesCmd(variableNames, executionId));
  }

  @Override
  public Map<String, Object> getVariables(String executionId) {
    return executor.execute(new GetVariablesCmd(executionId));
  }

}
